/* Archive Extractor
 * Copyright 2008-2009 Matthew Hoops
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * $URL: http://archive-extractor.googlecode.com/svn/trunk/archive.h $
 * $Id: archive.h 2 2009-03-23 01:29:43Z clone2727 $
 *
 */

#ifndef ARCHIVE_H
#define ARCHIVE_H

#include <cstdio>
#include <vector>

// An Archive is a representation of a type of archive format. For example, the Zip Archive (which
// derives from this class) is a representation of a Zip file (*.zip).
class Archive {
public:
	Archive() {}
	virtual ~Archive() {}
	
	// Return a list of extensions that this format can be found in. The extension can also take on
	// wildcard '?' characters which means any character can go in that slot. For example:
	//      Extension = "??_"   -------->  "BITMPC.EX_"
	virtual std::vector<const char*> getArchiveExtensions() = 0;
	
	// Return the name of the archive.
	virtual const char* getArchiveName() = 0;
	
	// Detect the archive by examining it's contents. Return a value between 0 and 100,
	// representing the possibility that the file is of this type.
	virtual int detect(const char* filename) = 0;
	
	// Extract files from the file. 
	virtual bool extractFiles(const char* filename) = 0;
	
	// If a file requires an output file name (from command line) to be able to extract data.
	// This is false by default.
	virtual bool requiresOutputFileName() { return false; }
};

// This archive uses a standard file for detection/extraction. It's basically just a wrapper.
class StandardArchive : public Archive {
public:
	StandardArchive() : Archive() {}
	virtual ~StandardArchive() {}
	
	// See Archive
	virtual std::vector<const char*> getArchiveExtensions() = 0;
	
	// See Archive
	virtual const char* getArchiveName() = 0;
	
	// A simple wrapper around detect to use the stdio function
	int detect(const char* filename) {
		FILE *file = fopen(filename, "rb");
		int result = detect(file);
		fclose(file);
		return result;
	}
	
	// A simple wrapper around detect to use the stdio function
	bool extractFiles(const char* filename) {
		FILE *file = fopen(filename, "rb");
		bool result = extractFiles(file);
		fclose(file);
		return result;
	}
	
	// Detect the archive by examining it's contents. Return a value between 0 and 100,
	// representing the possibility that the file is of this type.
	virtual int detect(FILE* file) = 0;
	
	// Extract files from the file.
	virtual bool extractFiles(FILE* file) = 0;
};

#endif
